package com.bluegalaxy.nhb.core;


import com.bluegalaxy.nhb.core.builder.JavaSqlInfoBuilder;
import com.bluegalaxy.nhb.core.builder.SqlInfoBuilder;
import com.bluegalaxy.nhb.util.StringHelper;
import com.bluegalaxy.nhb.core.helpers.CollectionHelper;
import com.bluegalaxy.nhb.domain.constant.SqlKeyConst;
import com.bluegalaxy.nhb.domain.constant.XxBuildConst;
import com.bluegalaxy.nhb.domain.vo.sql.BuildSource;
import com.bluegalaxy.nhb.domain.vo.sql.SqlInfo;

import java.util.Collection;
import java.util.Collections;

/**
 * 构造Zealot的Java链式SQL和参数的类.
 * @author blinkfox on 2017-03-31.
 */
public final class XxSqlJoin {

    /**
     * 封装了SqlInfo、应用中提供的上下文参数、前缀等信息.由于这里是纯Java拼接,所以就没有xml的Node节点信息，初始为为null.
     */
    private BuildSource source;

    /**
     * 私有构造方法，构造时就初始化BuildSource相应的参数信息.
     */
    private XxSqlJoin() {
        this.source = new BuildSource(SqlInfo.newInstance());
    }

    /**
     * 开始的方法.
     *
     * @return XxSqlJoin实例
     */
    public static XxSqlJoin start() {
        return new XxSqlJoin();
    }

    /**
     * 结束SQL拼接流程，并生成最终的sqlInfo信息.
     *
     * @return sqlInfo
     */
    public SqlInfo end() {
        SqlInfo sqlInfo = this.source.getSqlInfo();
        sqlInfo.setSql(StringHelper.replaceBlank(sqlInfo.getJoin().toString()));
//        SqlInfoPrinter.newInstance().printZealotSqlInfo(sqlInfo, false, null, null);
        return sqlInfo;
    }

    /**
     * 连接字符串.
     *
     * @param sqlKey sql关键字
     * @param params 其他若干字符串参数
     */
    private XxSqlJoin concat(String sqlKey, String... params) {
        this.source.getSqlInfo().getJoin().append(SqlKeyConst.SPACE).append(sqlKey).append(SqlKeyConst.SPACE);
        if (params != null && params.length > 0) {
            for (String s : params) {
                this.source.getSqlInfo().getJoin().append(s).append(SqlKeyConst.SPACE);
            }
        }
        return this;
    }

    /**
     * 拼接并带上'INSERT_INTO'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin insertInto(String text) {
        return concat(SqlKeyConst.INSERT_INTO, text);
    }

    /**
     * 拼接并带上'VALUES'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin values(String text) {
        return concat(SqlKeyConst.VALUES, text);
    }

    /**
     * 拼接并带上'DELETE FROM'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin deleteFrom(String text) {
        return concat(SqlKeyConst.DELETE_FROM, text);
    }

    /**
     * 拼接并带上'UPDATE'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin update(String text) {
        return concat(SqlKeyConst.UPDATE, text);
    }

    /**
     * 拼接并带上'SELECT'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin select(String text) {
        return concat(SqlKeyConst.SELECT, text);
    }

    /**
     * 拼接并带上'FROM'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin from(String text) {
        return concat(SqlKeyConst.FROM, text);
    }

    /**
     * 拼接并带上'WHERE'关键字的字符串和动态参数.
     *
     * @param text  文本
     * @param value 参数值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin where(String text, Object... value) {
        concat(SqlKeyConst.WHERE, text);
        return this.param(value);
    }

    /**
     * 拼接并带上'AND'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin and(String text) {
        return concat(SqlKeyConst.AND, text);
    }

    /**
     * 拼接并带上'OR'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin or(String text) {
        return concat(SqlKeyConst.OR, text);
    }

    /**
     * 拼接并带上'AS'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin as(String text) {
        return concat(SqlKeyConst.AS, text);
    }

    /**
     * 拼接并带上'AS'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin set(String text) {
        return concat(SqlKeyConst.SET, text);
    }

    /**
     * 拼接并带上'INNER JOIN'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin innerJoin(String text) {
        return concat(SqlKeyConst.INNER_JOIN, text);
    }

    /**
     * 拼接并带上'LEFT JOIN'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin leftJoin(String text) {
        return concat(SqlKeyConst.LEFT_JOIN, text);
    }

    /**
     * 拼接并带上'RIGHT JOIN'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin rightJoin(String text) {
        return concat(SqlKeyConst.RIGHT_JOIN, text);
    }

    /**
     * 拼接并带上'FULL JOIN'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin fullJoin(String text) {
        return concat(SqlKeyConst.FULL_JOIN, text);
    }

    /**
     * 拼接并带上'ON'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin on(String text) {
        return concat(SqlKeyConst.ON, text);
    }

    /**
     * 拼接并带上'ORDER BY'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orderBy(String text) {
        return concat(SqlKeyConst.ORDER_BY, text);
    }

    /**
     * 拼接并带上'GROUP BY'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin groupBy(String text) {
        return concat(SqlKeyConst.GROUP_BY, text);
    }

    /**
     * 拼接并带上'HAVING'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin having(String text) {
        return concat(SqlKeyConst.HAVING, text);
    }

    /**
     * 拼接并带上'LIMIT'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin limit(String text) {
        return concat(SqlKeyConst.LIMIT, text);
    }

    /**
     * 拼接并带上'OFFSET'关键字的字符串.
     *
     * @param text 文本
     * @return XxSqlJoin实例
     */
    public XxSqlJoin offset(String text) {
        return concat(SqlKeyConst.OFFSET, text);
    }

    /**
     * 拼接并带上'ASC'关键字的字符串.
     *
     * @return XxSqlJoin实例
     */
    public XxSqlJoin asc() {
        return concat(SqlKeyConst.ASC);
    }

    /**
     * 拼接并带上'DESC'关键字的字符串.
     *
     * @return XxSqlJoin实例
     */
    public XxSqlJoin desc() {
        return concat(SqlKeyConst.DESC);
    }

    /**
     * 拼接并带上'UNION'关键字的字符串.
     *
     * @return XxSqlJoin实例
     */
    public XxSqlJoin union() {
        return concat(SqlKeyConst.UNION);
    }

    /**
     * 拼接并带上'UNION ALL'关键字的字符串.
     *
     * @return XxSqlJoin实例
     */
    public XxSqlJoin unionAll() {
        return concat(SqlKeyConst.UNION_ALL);
    }

    /**
     * 在sql后追加任何文本字符串，后可追加自定义可变参数.
     *
     * @param text   文本
     * @param values 可变参数数组
     * @return XxSqlJoin实例
     */
    public XxSqlJoin text(String text, Object... values) {
        this.source.getSqlInfo().getJoin().append(text);
        this.appendParams(values, XxBuildConst.OBJTYPE_ARRAY);
        return this;
    }

    /**
     * 在sql后追加任何文本字符串，后可追加自定义可变参数，如果match为true时，才生成此SQL文本和参数.
     *
     * @param match  匹配条件
     * @param text   文本
     * @param values 可变参数数组
     * @return XxSqlJoin实例
     */
    public XxSqlJoin text(boolean match, String text, Object... values) {
        return match ? text(text, values) : this;
    }

    /**
     * 在sql的参数集合后追加任何的数组.
     *
     * @param value   值
     * @param objType 对象类型那
     * @return XxSqlJoin实例
     */
    private XxSqlJoin appendParams(Object value, int objType) {
        Object[] values = CollectionHelper.toArray(value, objType);
        if (CollectionHelper.isNotEmpty(values)) {
            Collections.addAll(this.source.getSqlInfo().getParams(), values);
        }
        return this;
    }

    /**
     * 在sql的参数集合后追加不定对象个数的数组.
     *
     * @param values 不定个数的值，也是数组
     * @return XxSqlJoin实例
     */
    public XxSqlJoin param(Object... values) {
        return this.appendParams(values, XxBuildConst.OBJTYPE_ARRAY);
    }

    /**
     * 在sql的参数集合后追加任何的一个集合.
     *
     * @param values 不定个数的值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin param(Collection<?> values) {
        return this.appendParams(values, XxBuildConst.OBJTYPE_COLLECTION);
    }

    /**
     * 执行自定义的任意操作.
     *
     * @param action 执行when条件中的方法
     * @return XxSqlJoin实例
     */
//    public XxSqlJoin doAnything(ICustomAction action) {
//        SqlInfo sqlInfo = this.source.getSqlInfo();
//        action.execute(sqlInfo.getJoin(), sqlInfo.getParams());
//        return this;
//    }

    /**
     * 当匹配match条件为true时，才执行自定义的任意操作.
     *
     * @param match  匹配条件
     * @param action 执行when条件中的方法
     * @return XxSqlJoin实例
     */
//    public XxSqlJoin doAnything(boolean match, ICustomAction action) {
//        return match ? this.doAnything(action) : this;
//    }

    /**
     * 执行生成等值查询SQL片段的方法.
     *
     * @param prefix 前缀
     * @param field  数据库字段
     * @param value  值
     * @param suffix 后缀
     * @param match  是否匹配
     * @return XxSqlJoin实例的当前实例
     */
    private XxSqlJoin doNormal(String prefix, String field, Object value, String suffix, boolean match) {
        if (match) {
            SqlInfoBuilder.newInstace(this.source.setPrefix(prefix)).buildNormalSql(field, value, suffix);
            this.source.resetPrefix();
        }
        return this;
    }

    /**
     * 执行生成like模糊查询SQL片段的方法.
     *
     * @param prefix   前缀
     * @param field    数据库字段
     * @param value    值
     * @param match    是否匹配
     * @param positive true则表示是like，否则是not like
     * @return XxSqlJoin实例的当前实例
     */
    private XxSqlJoin doLike(String prefix, String field, Object value, boolean match, boolean positive) {
        if (match) {
            String suffix = positive ? XxBuildConst.LIKE_KEY : XxBuildConst.NOT_LIKE_KEY;
            SqlInfoBuilder.newInstace(this.source.setPrefix(prefix).setSuffix(suffix)).buildLikeSql(field, value);
            this.source.resetPrefix();
        }
        return this;
    }

    /**
     * 执行根据传入模式来生成like匹配SQL片段的方法.
     *
     * @param prefix   前缀
     * @param field    数据库字段
     * @param pattern  值
     * @param match    是否匹配
     * @param positive true则表示是like，否则是not like
     * @return XxSqlJoin实例的当前实例
     */
    private XxSqlJoin doLikePattern(String prefix, String field, String pattern, boolean match, boolean positive) {
        if (match) {
            String suffix = positive ? XxBuildConst.LIKE_KEY : XxBuildConst.NOT_LIKE_KEY;
            SqlInfoBuilder.newInstace(this.source.setPrefix(prefix).setSuffix(suffix))
                    .buildLikePatternSql(field, pattern);
            this.source.resetPrefix();
        }
        return this;
    }

    /**
     * 执行生成like模糊查询SQL片段的方法.
     *
     * @param prefix     前缀
     * @param field      数据库字段
     * @param startValue 值
     * @param endValue   值
     * @param match      是否匹配
     * @return XxSqlJoin实例的当前实例
     */
    private XxSqlJoin doBetween(String prefix, String field, Object startValue, Object endValue, boolean match) {
        if (match) {
            SqlInfoBuilder.newInstace(this.source.setPrefix(prefix)).buildBetweenSql(field, startValue, endValue);
            this.source.resetPrefix();
        }
        return this;
    }

    /**
     * 执行生成in范围查询SQL片段的方法,如果是集合或数组，则执行生成，否则抛出异常.
     *
     * @param prefix   前缀
     * @param field    数据库字段
     * @param value    数组的值
     * @param match    是否匹配
     * @param objType  对象类型，取自XxBuildConst.java中以OBJTYPE开头的类型
     * @param positive true则表示是in，否则是not in
     * @return XxSqlJoin实例的当前实例
     */
    @SuppressWarnings("unchecked")
    private XxSqlJoin doInByType(String prefix, String field, Object value,
                                 boolean match, int objType, boolean positive) {
        if (match) {
            // 赋予source对象in SQL片段的前缀和后缀操作符.
            this.source.setPrefix(prefix).setSuffix(positive ? XxBuildConst.IN_SUFFIX : XxBuildConst.NOT_IN_SUFFIX);
            // 根据对象类型调用对应的生成in查询的sql片段方法,否则抛出类型不符合的异常
            switch (objType) {
                // 如果类型是数组.
                case XxBuildConst.OBJTYPE_ARRAY:
                    SqlInfoBuilder.newInstace(source).buildInSql(field, (Object[]) value);
                    break;
                // 如果类型是Java集合.
                case XxBuildConst.OBJTYPE_COLLECTION:
                    JavaSqlInfoBuilder.newInstace(source).buildInSqlByCollection(field, (Collection<Object>) value);
                    break;
                default:
                    SqlInfoBuilder.newInstace(source).buildInSql(field, (Object[]) value);;
            }
            this.source.resetPrefix();
        }
        return this;
    }

    /**
     * 执行生成in范围查询SQL片段的方法.
     *
     * @param prefix   前缀
     * @param field    数据库字段
     * @param values   数组的值
     * @param match    是否匹配
     * @param positive true则表示是in，否则是not in
     * @return XxSqlJoin实例的当前实例
     */
    private XxSqlJoin doIn(String prefix, String field, Object[] values, boolean match, boolean positive) {
        return this.doInByType(prefix, field, values, match, XxBuildConst.OBJTYPE_ARRAY, positive);
    }

    /**
     * 执行生成in范围查询SQL片段的方法.
     *
     * @param prefix   前缀
     * @param field    数据库字段
     * @param values   集合的值
     * @param match    是否匹配
     * @param positive true则表示是in，否则是not in
     * @return XxSqlJoin实例的当前实例
     */
    private XxSqlJoin doIn(String prefix, String field, Collection<?> values, boolean match, boolean positive) {
        return this.doInByType(prefix, field, values, match, XxBuildConst.OBJTYPE_COLLECTION, positive);
    }

    /**
     * 执行生成" IS NULL "SQL片段的方法.
     *
     * @param prefix   前缀
     * @param field    数据库字段
     * @param match    是否匹配
     * @param positive true则表示是 IS NULL，否则是IS NOT NULL
     * @return XxSqlJoin实例的当前实例
     */
    private XxSqlJoin doIsNull(String prefix, String field, boolean match, boolean positive) {
        if (match) {
            // 判断是"IS NULL"还是"IS NOT NULL"来设置source实例.
            this.source = this.source.setPrefix(prefix)
                    .setSuffix(positive ? XxBuildConst.IS_NULL_SUFFIX : XxBuildConst.IS_NOT_NULL_SUFFIX);
            SqlInfoBuilder.newInstace(this.source).buildIsNullSql(field);
            this.source.resetPrefix();
        }
        return this;
    }

    /**
     * 生成等值查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin equal(String field, Object value) {
        return this.doNormal(XxBuildConst.ONE_SPACE, field, value, XxBuildConst.EQUAL_SUFFIX, true);
    }

    /**
     * 生成等值查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin equal(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.ONE_SPACE, field, value, XxBuildConst.EQUAL_SUFFIX, match);
    }

    /**
     * 生成带" AND "前缀等值查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andEqual(String field, Object value) {
        return this.doNormal(XxBuildConst.AND_PREFIX, field, value, XxBuildConst.EQUAL_SUFFIX, true);
    }

    /**
     * 生成带" AND "前缀等值查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andEqual(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.AND_PREFIX, field, value, XxBuildConst.EQUAL_SUFFIX, match);
    }

    /**
     * 生成带" OR "前缀等值查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orEqual(String field, Object value) {
        return this.doNormal(XxBuildConst.OR_PREFIX, field, value, XxBuildConst.EQUAL_SUFFIX, true);
    }

    /**
     * 生成带" OR "前缀等值查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orEqual(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.OR_PREFIX, field, value, XxBuildConst.EQUAL_SUFFIX, match);
    }

    /**
     * 生成不等查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin notEqual(String field, Object value) {
        return this.doNormal(XxBuildConst.ONE_SPACE, field, value, XxBuildConst.NOT_EQUAL_SUFFIX, true);
    }

    /**
     * 生成不等查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin notEqual(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.ONE_SPACE, field, value, XxBuildConst.NOT_EQUAL_SUFFIX, match);
    }

    /**
     * 生成带" AND "前缀不等查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andNotEqual(String field, Object value) {
        return this.doNormal(XxBuildConst.AND_PREFIX, field, value, XxBuildConst.NOT_EQUAL_SUFFIX, true);
    }

    /**
     * 生成带" AND "前缀不等查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andNotEqual(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.AND_PREFIX, field, value, XxBuildConst.NOT_EQUAL_SUFFIX, match);
    }

    /**
     * 生成带" OR "前缀不等查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orNotEqual(String field, Object value) {
        return this.doNormal(XxBuildConst.OR_PREFIX, field, value, XxBuildConst.NOT_EQUAL_SUFFIX, true);
    }

    /**
     * 生成带" OR "前缀不等查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orNotEqual(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.OR_PREFIX, field, value, XxBuildConst.NOT_EQUAL_SUFFIX, match);
    }

    /**
     * 生成大于查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin moreThan(String field, Object value) {
        return this.doNormal(XxBuildConst.ONE_SPACE, field, value, XxBuildConst.GT_SUFFIX, true);
    }

    /**
     * 生成大于查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin moreThan(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.ONE_SPACE, field, value, XxBuildConst.GT_SUFFIX, match);
    }

    /**
     * 生成带" AND "前缀大于查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andMoreThan(String field, Object value) {
        return this.doNormal(XxBuildConst.AND_PREFIX, field, value, XxBuildConst.GT_SUFFIX, true);
    }

    /**
     * 生成带" AND "前缀大于查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andMoreThan(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.AND_PREFIX, field, value, XxBuildConst.GT_SUFFIX, match);
    }

    /**
     * 生成带" OR "前缀大于查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orMoreThan(String field, Object value) {
        return this.doNormal(XxBuildConst.OR_PREFIX, field, value, XxBuildConst.GT_SUFFIX, true);
    }

    /**
     * 生成带" OR "前缀大于查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orMoreThan(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.OR_PREFIX, field, value, XxBuildConst.GT_SUFFIX, match);
    }

    /**
     * 生成小于查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin lessThan(String field, Object value) {
        return this.doNormal(XxBuildConst.ONE_SPACE, field, value, XxBuildConst.LT_SUFFIX, true);
    }

    /**
     * 生成小于查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin lessThan(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.ONE_SPACE, field, value, XxBuildConst.LT_SUFFIX, match);
    }

    /**
     * 生成带" AND "前缀小于查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andLessThan(String field, Object value) {
        return this.doNormal(XxBuildConst.AND_PREFIX, field, value, XxBuildConst.LT_SUFFIX, true);
    }

    /**
     * 生成带" AND "前缀小于查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andLessThan(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.AND_PREFIX, field, value, XxBuildConst.LT_SUFFIX, match);
    }

    /**
     * 生成带" OR "前缀小于查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orLessThan(String field, Object value) {
        return this.doNormal(XxBuildConst.OR_PREFIX, field, value, XxBuildConst.LT_SUFFIX, true);
    }

    /**
     * 生成带" OR "前缀小于查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orLessThan(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.OR_PREFIX, field, value, XxBuildConst.LT_SUFFIX, match);
    }

    /**
     * 生成大于等于查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin moreEqual(String field, Object value) {
        return this.doNormal(XxBuildConst.ONE_SPACE, field, value, XxBuildConst.GTE_SUFFIX, true);
    }

    /**
     * 生成大于等于查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin moreEqual(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.ONE_SPACE, field, value, XxBuildConst.GTE_SUFFIX, match);
    }

    /**
     * 生成带" AND "前缀大于等于查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andMoreEqual(String field, Object value) {
        return this.doNormal(XxBuildConst.AND_PREFIX, field, value, XxBuildConst.GTE_SUFFIX, true);
    }

    /**
     * 生成带" AND "前缀大于等于查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andMoreEqual(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.AND_PREFIX, field, value, XxBuildConst.GTE_SUFFIX, match);
    }

    /**
     * 生成带" OR "前缀大于等于查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orMoreEqual(String field, Object value) {
        return this.doNormal(XxBuildConst.OR_PREFIX, field, value, XxBuildConst.GTE_SUFFIX, true);
    }

    /**
     * 生成带" OR "前缀大于等于查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orMoreEqual(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.OR_PREFIX, field, value, XxBuildConst.GTE_SUFFIX, match);
    }

    /**
     * 生成小于等于查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin lessEqual(String field, Object value) {
        return this.doNormal(XxBuildConst.ONE_SPACE, field, value, XxBuildConst.LTE_SUFFIX, true);
    }

    /**
     * 生成小于等于查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin lessEqual(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.ONE_SPACE, field, value, XxBuildConst.LTE_SUFFIX, match);
    }

    /**
     * 生成带" AND "前缀小于等于查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andLessEqual(String field, Object value) {
        return this.doNormal(XxBuildConst.AND_PREFIX, field, value, XxBuildConst.LTE_SUFFIX, true);
    }

    /**
     * 生成带" AND "前缀小于等于查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andLessEqual(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.AND_PREFIX, field, value, XxBuildConst.LTE_SUFFIX, match);
    }

    /**
     * 生成带" OR "前缀小于等于查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orLessEqual(String field, Object value) {
        return this.doNormal(XxBuildConst.OR_PREFIX, field, value, XxBuildConst.LTE_SUFFIX, true);
    }

    /**
     * 生成带" OR "前缀小于等于查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orLessEqual(String field, Object value, boolean match) {
        return this.doNormal(XxBuildConst.OR_PREFIX, field, value, XxBuildConst.LTE_SUFFIX, match);
    }

    /**
     * 生成like模糊查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin like(String field, Object value) {
        return this.doLike(XxBuildConst.ONE_SPACE, field, value, true, true);
    }

    /**
     * 生成like模糊查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin like(String field, Object value, boolean match) {
        return this.doLike(XxBuildConst.ONE_SPACE, field, value, match, true);
    }

    /**
     * 生成带" AND "前缀的like模糊查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andLike(String field, Object value) {
        return this.doLike(XxBuildConst.AND_PREFIX, field, value, true, true);
    }

    /**
     * 生成带" AND "前缀的like模糊查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andLike(String field, Object value, boolean match) {
        return this.doLike(XxBuildConst.AND_PREFIX, field, value, match, true);
    }

    /**
     * 生成带" OR "前缀的like模糊查询的SQL片段.
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orLike(String field, Object value) {
        return this.doLike(XxBuildConst.OR_PREFIX, field, value, true, true);
    }

    /**
     * 生成带" OR "前缀的like模糊查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orLike(String field, Object value, boolean match) {
        return this.doLike(XxBuildConst.OR_PREFIX, field, value, match, true);
    }

    /**
     * 生成" NOT LIKE "模糊查询的SQL片段.
     * <p>示例：传入 {"b.title", "Spring"} 两个参数，生成的SQL片段为：" b.title NOT LIKE ? ", SQL参数为:{"%Spring%"}</p>
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin notLike(String field, Object value) {
        return this.doLike(XxBuildConst.ONE_SPACE, field, value, true, false);
    }

    /**
     * 生成" NOT LIKE "模糊查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     * <p>示例：传入 {"b.title", "Spring", true} 三个参数，生成的SQL片段为：" b.title NOT LIKE ? ", SQL参数为:{"%Spring%"}</p>
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin notLike(String field, Object value, boolean match) {
        return this.doLike(XxBuildConst.ONE_SPACE, field, value, match, false);
    }

    /**
     * 生成带" AND "前缀的" NOT LIKE "模糊查询的SQL片段.
     * <p>示例：传入 {"b.title", "Spring"} 两个参数，生成的SQL片段为：" AND b.title NOT LIKE ? ", SQL参数为:{"%Spring%"}</p>
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andNotLike(String field, Object value) {
        return this.doLike(XxBuildConst.AND_PREFIX, field, value, true, false);
    }

    /**
     * 生成带" AND "前缀的" NOT LIKE "模糊查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     * <p>示例：传入 {"b.title", "Spring", true} 三个参数，生成的SQL片段为：" AND b.title NOT LIKE ? ", SQL参数为:{"%Spring%"}</p>
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andNotLike(String field, Object value, boolean match) {
        return this.doLike(XxBuildConst.AND_PREFIX, field, value, match, false);
    }

    /**
     * 生成带" OR "前缀的" NOT LIKE "模糊查询的SQL片段.
     * <p>示例：传入 {"b.title", "Spring"} 两个参数，生成的SQL片段为：" OR b.title NOT LIKE ? ", SQL参数为:{"%Spring%"}</p>
     *
     * @param field 数据库字段
     * @param value 值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orNotLike(String field, Object value) {
        return this.doLike(XxBuildConst.OR_PREFIX, field, value, true, false);
    }

    /**
     * 生成带" OR "前缀的" NOT LIKE "模糊查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     * <p>示例：传入 {"b.title", "Spring", true} 三个参数，生成的SQL片段为：" OR b.title NOT LIKE ? ", SQL参数为:{"%Spring%"}</p>
     *
     * @param field 数据库字段
     * @param value 值
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orNotLike(String field, Object value, boolean match) {
        return this.doLike(XxBuildConst.OR_PREFIX, field, value, match, false);
    }

    /**
     * 根据指定的模式字符串生成like模糊查询的SQL片段.
     * <p>示例：传入 {"b.title", "Java%"} 两个参数，生成的SQL片段为：" b.title LIKE 'Java%' "</p>
     *
     * @param field   数据库字段
     * @param pattern 模式字符串
     * @return XxSqlJoin实例
     */
    public XxSqlJoin likePattern(String field, String pattern) {
        return this.doLikePattern(XxBuildConst.ONE_SPACE, field, pattern, true, true);
    }

    /**
     * 根据指定的模式字符串生成like模糊查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     * <p>示例：传入 {"b.title", "Java%", true} 三个参数，生成的SQL片段为：" b.title LIKE 'Java%' "</p>
     * <p>示例：传入 {"b.title", "Java%", false} 三个参数，生成的SQL片段为空字符串.</p>
     *
     * @param field   数据库字段
     * @param pattern 模式字符串
     * @param match   是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin likePattern(String field, String pattern, boolean match) {
        return this.doLikePattern(XxBuildConst.ONE_SPACE, field, pattern, match, true);
    }

    /**
     * 根据指定的模式字符串生成带" AND "前缀的like模糊查询的SQL片段.
     * <p>示例：传入 {"b.title", "Java%"} 两个参数，生成的SQL片段为：" AND b.title LIKE 'Java%' "</p>
     *
     * @param field   数据库字段
     * @param pattern 模式字符串
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andLikePattern(String field, String pattern) {
        return this.doLikePattern(XxBuildConst.AND_PREFIX, field, pattern, true, true);
    }

    /**
     * 根据指定的模式字符串生成带" AND "前缀的like模糊查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     * <p>示例：传入 {"b.title", "Java%", true} 三个参数，生成的SQL片段为：" AND b.title LIKE 'Java%' "</p>
     * <p>示例：传入 {"b.title", "Java%", false} 三个参数，生成的SQL片段为空字符串.</p>
     *
     * @param field   数据库字段
     * @param pattern 模式字符串
     * @param match   是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andLikePattern(String field, String pattern, boolean match) {
        return this.doLikePattern(XxBuildConst.AND_PREFIX, field, pattern, match, true);
    }

    /**
     * 根据指定的模式字符串生成带" OR "前缀的like模糊查询的SQL片段.
     * <p>示例：传入 {"b.title", "Java%"} 两个参数，生成的SQL片段为：" OR b.title LIKE 'Java%' "</p>
     *
     * @param field   数据库字段
     * @param pattern 模式字符串
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orLikePattern(String field, String pattern) {
        return this.doLikePattern(XxBuildConst.OR_PREFIX, field, pattern, true, true);
    }

    /**
     * 根据指定的模式字符串生成带" OR "前缀的like模糊查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     * <p>示例：传入 {"b.title", "Java%", true} 三个参数，生成的SQL片段为：" OR b.title LIKE 'Java%' "</p>
     * <p>示例：传入 {"b.title", "Java%", false} 三个参数，生成的SQL片段为空字符串.</p>
     *
     * @param field   数据库字段
     * @param pattern 模式字符串
     * @param match   是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orLikePattern(String field, String pattern, boolean match) {
        return this.doLikePattern(XxBuildConst.OR_PREFIX, field, pattern, match, true);
    }

    /**
     * 根据指定的模式字符串生成" NOT LIKE "模糊查询的SQL片段.
     * <p>示例：传入 {"b.title", "Java%"} 两个参数，生成的SQL片段为：" b.title NOT LIKE 'Java%' "</p>
     *
     * @param field   数据库字段
     * @param pattern 模式字符串
     * @return XxSqlJoin实例
     */
    public XxSqlJoin notLikePattern(String field, String pattern) {
        return this.doLikePattern(XxBuildConst.ONE_SPACE, field, pattern, true, false);
    }

    /**
     * 根据指定的模式字符串生成" NOT LIKE "模糊查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     * <p>示例：传入 {"b.title", "Java%", true} 三个参数，生成的SQL片段为：" b.title NOT LIKE 'Java%' "</p>
     * <p>示例：传入 {"b.title", "Java%", false} 三个参数，生成的SQL片段为空字符串.</p>
     *
     * @param field   数据库字段
     * @param pattern 模式字符串
     * @param match   是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin notLikePattern(String field, String pattern, boolean match) {
        return this.doLikePattern(XxBuildConst.ONE_SPACE, field, pattern, match, false);
    }

    /**
     * 根据指定的模式字符串生成带" AND "前缀的" NOT LIKE "模糊查询的SQL片段.
     * <p>示例：传入 {"b.title", "Java%"} 两个参数，生成的SQL片段为：" AND b.title NOT LIKE 'Java%' "</p>
     *
     * @param field   数据库字段
     * @param pattern 模式字符串
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andNotLikePattern(String field, String pattern) {
        return this.doLikePattern(XxBuildConst.AND_PREFIX, field, pattern, true, false);
    }

    /**
     * 根据指定的模式字符串生成带" AND "前缀的" NOT LIKE "模糊查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     * <p>示例：传入 {"b.title", "Java%", true} 三个参数，生成的SQL片段为：" AND b.title NOT LIKE 'Java%' "</p>
     * <p>示例：传入 {"b.title", "Java%", false} 三个参数，生成的SQL片段为空字符串.</p>
     *
     * @param field   数据库字段
     * @param pattern 模式字符串
     * @param match   是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andNotLikePattern(String field, String pattern, boolean match) {
        return this.doLikePattern(XxBuildConst.AND_PREFIX, field, pattern, match, false);
    }

    /**
     * 根据指定的模式字符串生成带" OR "前缀的" NOT LIKE "模糊查询的SQL片段.
     * <p>示例：传入 {"b.title", "Java%"} 两个参数，生成的SQL片段为：" OR b.title NOT LIKE 'Java%' "</p>
     *
     * @param field   数据库字段
     * @param pattern 模式字符串
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orNotLikePattern(String field, String pattern) {
        return this.doLikePattern(XxBuildConst.OR_PREFIX, field, pattern, true, false);
    }

    /**
     * 根据指定的模式字符串生成带" OR "前缀的" NOT LIKE "模糊查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     * <p>示例：传入 {"b.title", "Java%", true} 三个参数，生成的SQL片段为：" OR b.title NOT LIKE 'Java%' "</p>
     * <p>示例：传入 {"b.title", "Java%", false} 三个参数，生成的SQL片段为空字符串.</p>
     *
     * @param field   数据库字段
     * @param pattern 模式字符串
     * @param match   是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orNotLikePattern(String field, String pattern, boolean match) {
        return this.doLikePattern(XxBuildConst.OR_PREFIX, field, pattern, match, false);
    }

    /**
     * 生成between区间查询的SQL片段(当某一个值为null时，会是大于等于或小于等于的情形).
     *
     * @param field      数据库字段
     * @param startValue 开始值
     * @param endValue   结束值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin between(String field, Object startValue, Object endValue) {
        return this.doBetween(XxBuildConst.ONE_SPACE, field, startValue, endValue, true);
    }

    /**
     * 生成between区间查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成(当某一个值为null时，会是大于等于或小于等于的情形).
     *
     * @param field      数据库字段
     * @param startValue 开始值
     * @param endValue   结束值
     * @param match      是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin between(String field, Object startValue, Object endValue, boolean match) {
        return this.doBetween(XxBuildConst.ONE_SPACE, field, startValue, endValue, match);
    }

    /**
     * 生成带" AND "前缀的between区间查询的SQL片段(当某一个值为null时，会是大于等于或小于等于的情形).
     *
     * @param field      数据库字段
     * @param startValue 开始值
     * @param endValue   结束值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andBetween(String field, Object startValue, Object endValue) {
        return this.doBetween(XxBuildConst.AND_PREFIX, field, startValue, endValue, true);
    }

    /**
     * 生成带" AND "前缀的between区间查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成(当某一个值为null时，会是大于等于或小于等于的情形).
     *
     * @param field      数据库字段
     * @param startValue 开始值
     * @param endValue   结束值
     * @param match      是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andBetween(String field, Object startValue, Object endValue, boolean match) {
        return this.doBetween(XxBuildConst.AND_PREFIX, field, startValue, endValue, match);
    }

    /**
     * 生成带" OR "前缀的between区间查询的SQL片段(当某一个值为null时，会是大于等于或小于等于的情形).
     *
     * @param field      数据库字段
     * @param startValue 开始值
     * @param endValue   结束值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orBetween(String field, Object startValue, Object endValue) {
        return this.doBetween(XxBuildConst.OR_PREFIX, field, startValue, endValue, true);
    }

    /**
     * 生成带" OR "前缀的between区间查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成(当某一个值为null时，会是大于等于或小于等于的情形).
     *
     * @param field      数据库字段
     * @param startValue 开始值
     * @param endValue   结束值
     * @param match      是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orBetween(String field, Object startValue, Object endValue, boolean match) {
        return this.doBetween(XxBuildConst.OR_PREFIX, field, startValue, endValue, match);
    }

    /**
     * 生成in范围查询的SQL片段.
     *
     * @param field  数据库字段
     * @param values 数组的值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin in(String field, Object[] values) {
        return this.doIn(XxBuildConst.ONE_SPACE, field, values, true, true);
    }

    /**
     * 生成in范围查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field  数据库字段
     * @param values 数组的值
     * @param match  是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin in(String field, Object[] values, boolean match) {
        return this.doIn(XxBuildConst.ONE_SPACE, field, values, match, true);
    }

    /**
     * 生成in范围查询的SQL片段.
     *
     * @param field  数据库字段
     * @param values 集合的值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin in(String field, Collection<?> values) {
        return this.doIn(XxBuildConst.ONE_SPACE, field, values, true, true);
    }

    /**
     * 生成in范围查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field  数据库字段
     * @param values 集合的值
     * @param match  是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin in(String field, Collection<?> values, boolean match) {
        return this.doIn(XxBuildConst.ONE_SPACE, field, values, match, true);
    }

    /**
     * 生成带" AND "前缀的in范围查询的SQL片段.
     *
     * @param field  数据库字段
     * @param values 数组的值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andIn(String field, Object[] values) {
        return this.doIn(XxBuildConst.AND_PREFIX, field, values, true, true);
    }

    /**
     * 生成带" AND "前缀的in范围查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field  数据库字段
     * @param values 数组的值
     * @param match  是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andIn(String field, Object[] values, boolean match) {
        return this.doIn(XxBuildConst.AND_PREFIX, field, values, match, true);
    }

    /**
     * 生成带" AND "前缀的in范围查询的SQL片段.
     *
     * @param field  数据库字段
     * @param values 集合的值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andIn(String field, Collection<?> values) {
        return this.doIn(XxBuildConst.AND_PREFIX, field, values, true, true);
    }

    /**
     * 生成带" AND "前缀的in范围查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field  数据库字段
     * @param values 集合的值
     * @param match  是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andIn(String field, Collection<?> values, boolean match) {
        return this.doIn(XxBuildConst.AND_PREFIX, field, values, match, true);
    }

    /**
     * 生成带" OR "前缀的in范围查询的SQL片段.
     *
     * @param field  数据库字段
     * @param values 数组的值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orIn(String field, Object[] values) {
        return this.doIn(XxBuildConst.OR_PREFIX, field, values, true, true);
    }

    /**
     * 生成带" OR "前缀的in范围查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field  数据库字段
     * @param values 数组的值
     * @param match  是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orIn(String field, Object[] values, boolean match) {
        return this.doIn(XxBuildConst.OR_PREFIX, field, values, match, true);
    }

    /**
     * 生成带" OR "前缀的in范围查询的SQL片段.
     *
     * @param field  数据库字段
     * @param values 集合的值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orIn(String field, Collection<?> values) {
        return this.doIn(XxBuildConst.OR_PREFIX, field, values, true, true);
    }

    /**
     * 生成带" OR "前缀的in范围查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field  数据库字段
     * @param values 集合的值
     * @param match  是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orIn(String field, Collection<?> values, boolean match) {
        return this.doIn(XxBuildConst.OR_PREFIX, field, values, match, true);
    }

    /**
     * 生成" NOT IN "范围查询的SQL片段.
     *
     * @param field  数据库字段
     * @param values 数组的值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin notIn(String field, Object[] values) {
        return this.doIn(XxBuildConst.ONE_SPACE, field, values, true, false);
    }

    /**
     * 生成" NOT IN "范围查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field  数据库字段
     * @param values 数组的值
     * @param match  是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin notIn(String field, Object[] values, boolean match) {
        return this.doIn(XxBuildConst.ONE_SPACE, field, values, match, false);
    }

    /**
     * 生成" NOT IN "范围查询的SQL片段.
     *
     * @param field  数据库字段
     * @param values 集合的值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin notIn(String field, Collection<?> values) {
        return this.doIn(XxBuildConst.ONE_SPACE, field, values, true, false);
    }

    /**
     * 生成" NOT IN "范围查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field  数据库字段
     * @param values 集合的值
     * @param match  是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin notIn(String field, Collection<?> values, boolean match) {
        return this.doIn(XxBuildConst.ONE_SPACE, field, values, match, false);
    }

    /**
     * 生成带" AND "前缀的" NOT IN "范围查询的SQL片段.
     *
     * @param field  数据库字段
     * @param values 数组的值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andNotIn(String field, Object[] values) {
        return this.doIn(XxBuildConst.AND_PREFIX, field, values, true, false);
    }

    /**
     * 生成带" AND "前缀的" NOT IN "范围查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field  数据库字段
     * @param values 数组的值
     * @param match  是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andNotIn(String field, Object[] values, boolean match) {
        return this.doIn(XxBuildConst.AND_PREFIX, field, values, match, false);
    }

    /**
     * 生成带" AND "前缀的" NOT IN "范围查询的SQL片段.
     *
     * @param field  数据库字段
     * @param values 集合的值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andNotIn(String field, Collection<?> values) {
        return this.doIn(XxBuildConst.AND_PREFIX, field, values, true, false);
    }

    /**
     * 生成带" AND "前缀的" NOT IN "范围查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field  数据库字段
     * @param values 集合的值
     * @param match  是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andNotIn(String field, Collection<?> values, boolean match) {
        return this.doIn(XxBuildConst.AND_PREFIX, field, values, match, false);
    }

    /**
     * 生成带" OR "前缀的" NOT IN "范围查询的SQL片段.
     *
     * @param field  数据库字段
     * @param values 数组的值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orNotIn(String field, Object[] values) {
        return this.doIn(XxBuildConst.OR_PREFIX, field, values, true, false);
    }

    /**
     * 生成带" OR "前缀的" NOT IN "范围查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field  数据库字段
     * @param values 数组的值
     * @param match  是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orNotIn(String field, Object[] values, boolean match) {
        return this.doIn(XxBuildConst.OR_PREFIX, field, values, match, false);
    }

    /**
     * 生成带" OR "前缀的" NOT IN "范围查询的SQL片段.
     *
     * @param field  数据库字段
     * @param values 集合的值
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orNotIn(String field, Collection<?> values) {
        return this.doIn(XxBuildConst.OR_PREFIX, field, values, true, false);
    }

    /**
     * 生成带" OR "前缀的" NOT IN "范围查询的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     *
     * @param field  数据库字段
     * @param values 集合的值
     * @param match  是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orNotIn(String field, Collection<?> values, boolean match) {
        return this.doIn(XxBuildConst.OR_PREFIX, field, values, match, false);
    }

    /**
     * 生成" IS NULL "的SQL片段.
     * <p>示例：传入 {"a.name"} 参数，生成的SQL片段为：" a.name IS NULL "</p>
     *
     * @param field 数据库字段
     * @return XxSqlJoin实例
     */
    public XxSqlJoin isNull(String field) {
        return this.doIsNull(XxBuildConst.ONE_SPACE, field, true, true);
    }

    /**
     * 生成" IS NULL "的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     * <p>示例：传入 {"a.name", true} 两个参数，生成的SQL片段为：" a.name IS NULL "</p>
     *
     * @param field 数据库字段
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin isNull(String field, boolean match) {
        return this.doIsNull(XxBuildConst.ONE_SPACE, field, match, true);
    }

    /**
     * 生成带" AND "前缀" IS NULL "的SQL片段.
     * <p>示例：传入 {"a.name"} 参数，生成的SQL片段为：" AND a.name IS NULL "</p>
     *
     * @param field 数据库字段
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andIsNull(String field) {
        return this.doIsNull(XxBuildConst.AND_PREFIX, field, true, true);
    }

    /**
     * 生成带" AND "前缀" IS NULL "的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     * <p>示例：传入 {"a.name", true} 两个参数，生成的SQL片段为：" AND a.name IS NULL "</p>
     *
     * @param field 数据库字段
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andIsNull(String field, boolean match) {
        return this.doIsNull(XxBuildConst.AND_PREFIX, field, match, true);
    }

    /**
     * 生成带" OR "前缀" IS NULL "的SQL片段.
     * <p>示例：传入 {"a.name"} 参数，生成的SQL片段为：" OR a.name IS NULL "</p>
     *
     * @param field 数据库字段
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orIsNull(String field) {
        return this.doIsNull(XxBuildConst.OR_PREFIX, field, true, true);
    }

    /**
     * 生成带" OR "前缀" IS NULL "的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     * <p>示例：传入 {"a.name", true} 两个参数，生成的SQL片段为：" OR a.name IS NULL "</p>
     *
     * @param field 数据库字段
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orIsNull(String field, boolean match) {
        return this.doIsNull(XxBuildConst.OR_PREFIX, field, match, true);
    }

    /**
     * 生成" IS NOT NULL "的SQL片段.
     * <p>示例：传入 {"a.name"} 参数，生成的SQL片段为：" a.name IS NOT NULL "</p>
     *
     * @param field 数据库字段
     * @return XxSqlJoin实例
     */
    public XxSqlJoin isNotNull(String field) {
        return this.doIsNull(XxBuildConst.ONE_SPACE, field, true, false);
    }

    /**
     * 生成" IS NOT NULL "的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     * <p>示例：传入 {"a.name", true} 两个参数，生成的SQL片段为：" a.name IS NOT NULL "</p>
     *
     * @param field 数据库字段
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin isNotNull(String field, boolean match) {
        return this.doIsNull(XxBuildConst.ONE_SPACE, field, match, false);
    }

    /**
     * 生成带" AND "前缀" IS NOT NULL "的SQL片段.
     * <p>示例：传入 {"a.name"} 参数，生成的SQL片段为：" AND a.name IS NOT NULL "</p>
     *
     * @param field 数据库字段
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andIsNotNull(String field) {
        return this.doIsNull(XxBuildConst.AND_PREFIX, field, true, false);
    }

    /**
     * 生成带" AND "前缀" IS NOT NULL "的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     * <p>示例：传入 {"a.name", true} 两个参数，生成的SQL片段为：" AND a.name IS NOT NULL "</p>
     *
     * @param field 数据库字段
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin andIsNotNull(String field, boolean match) {
        return this.doIsNull(XxBuildConst.AND_PREFIX, field, match, false);
    }

    /**
     * 生成带" OR "前缀" IS NOT NULL "的SQL片段.
     * <p>示例：传入 {"a.name"} 参数，生成的SQL片段为：" OR a.name IS NOT NULL "</p>
     *
     * @param field 数据库字段
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orIsNotNull(String field) {
        return this.doIsNull(XxBuildConst.OR_PREFIX, field, true, false);
    }

    /**
     * 生成带" OR "前缀" IS NOT NULL "的SQL片段,如果match为true时则生成该条SQL片段，否则不生成.
     * <p>示例：传入 {"a.name", true} 两个参数，生成的SQL片段为：" OR a.name IS NOT NULL "</p>
     *
     * @param field 数据库字段
     * @param match 是否匹配
     * @return XxSqlJoin实例
     */
    public XxSqlJoin orIsNotNull(String field, boolean match) {
        return this.doIsNull(XxBuildConst.OR_PREFIX, field, match, false);
    }
}